<script setup lang="ts">
import type { Dict } from '@croco/framework/types';

import { onBeforeMount, reactive, ref } from 'vue';

import { Page } from '@croco/framework/libraries';

import { getDictTrim } from '#/api';
import { service } from '#/api/request';
import { DataTable } from '#/components/data-table';

import { useTable } from './data';
import Edit from './edit.vue';
import Log from './log.vue';

defineOptions({ name: 'Job' });

const dataTableRef = ref<InstanceType<typeof DataTable>>();
const editRef = ref<InstanceType<typeof Edit>>();
const logRef = ref<InstanceType<typeof Log>>();
const enums = reactive<{
    concurrent: Array<Dict> | undefined;
    groupName: Array<Dict> | undefined;
    misfirePolicy: Array<Dict> | undefined;
    result: Array<Dict> | undefined;
    status: Array<Dict> | undefined;
}>({
    concurrent: undefined,
    groupName: undefined,
    misfirePolicy: undefined,
    result: undefined,
    status: undefined,
});
const columns = useTable(enums, ({ code, scope }) => {
    switch (code) {
        case 'edit': {
            onEdit(scope.row);
            break;
        }
        case 'log': {
            logRef.value?.open(scope.row);
            break;
        }
        case 'remove': {
            onDelete([scope.row]);
            break;
        }
        case 'run': {
            onRun(scope.row);
            break;
        }
        default: {
            break;
        }
    }
});

// 表单
function onEdit(row?: any) {
    if (!row) {
        row = {};
        Object.entries(enums).forEach(([key, value]) => {
            const defaultValue = ['concurrent', 'status'].includes(key)
                ? Object.values(value!!).find((item) => item.isDefault === 'N')
                : Object.values(value!!).find((item) => item.isDefault === 'Y');
            row[key] = defaultValue?.value ?? '';
        });
    }
    editRef.value?.open({
        data: row,
        success: dataTableRef.value?.refresh,
    });
}

function onDelete(rows: any[]) {
    const ids = rows.map((item) => item.id);
    service.confirm({
        message: `确定对所选记录进行${ids.length === 1 ? '删除' : '批量删除'}操作,该操作不可逆?`,
        url: '/job',
        data: { id: ids },
        success: dataTableRef.value?.refresh,
    });
}

async function onRun(row: any) {
    const { data } = await service.get('/job/next', { cronExpression: row.cronExpression });
    service.confirm({
        message: `确定执行一次【${row.name}】任务, 运行时间：${data}?`,
        url: '/job/run',
        type: 'get',
        data: { id: row.id },
    });
}

onBeforeMount(() => {
    // 获取字典数据
    getDictTrim(['sys_yes_no', 'sys_job_group', 'sys_job_policy', 'sys_job_status', 'sys_common_status']).then((rs) => {
        enums.concurrent = rs[0] ?? [];
        enums.groupName = rs[1] ?? [];
        enums.misfirePolicy = rs[2] ?? [];
        enums.status = rs[3] ?? [];
        enums.result = rs[4] ?? [];
    });
});
</script>

<template>
    <Page auto-content-height>
        <DataTable ref="dataTableRef" :columns="columns" api="/job" selection select-on-row-click>
            <template #extra="{ selections }">
                <el-button v-auth="'system:user:add'" @click="onEdit()" />
                <el-button v-auth="'system:user:remove'" @click="onDelete(selections)" :disabled="selections.length <= 0" type="danger" />
            </template>
            <template #groupName="{ form }">
                <el-select v-model="form.groupName" :empty-values="[null, undefined]">
                    <el-option label="全部" value="" />
                    <el-option v-for="(item, index) in enums.groupName" :key="index" :label="item.label" :value="item.value" />
                </el-select>
            </template>
            <template #status="{ form }">
                <el-select v-model="form.status" :empty-values="[null, undefined]">
                    <el-option label="全部" value="" />
                    <el-option v-for="(item, index) in enums.status" :key="index" :label="item.label" :value="item.value" />
                </el-select>
            </template>
        </DataTable>

        <Edit ref="editRef" :enums="enums" />

        <Log ref="logRef" :enums="enums" />
    </Page>
</template>

<style scoped></style>
